package com.cskaoyan.market.service;

import com.cskaoyan.market.config.SystemConfig;
import com.cskaoyan.market.db.domain.*;
import com.cskaoyan.market.db.mapper.*;
import com.cskaoyan.market.vo.WxFloorGoodsVo;
import com.cskaoyan.market.vo.WxHomeIndexVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@Service
public class WxHomeServiceImpl_thread implements WxHomeService {

    @Autowired
    SystemConfig systemConfig;

    @Autowired
    MarketAdMapper marketAdMapper;

    @Autowired
    MarketBrandMapper marketBrandMapper;

    @Autowired
    MarketCategoryMapper marketCategoryMapper;

    @Autowired
    MarketCouponMapper marketCouponMapper;

    @Autowired
    MarketGoodsMapper marketGoodsMapper;

    @Autowired
    MarketTopicMapper marketTopicMapper;

    @Autowired
    MarketCouponUserMapper marketCouponUserMapper;

    @Override
    public WxHomeIndexVo index(MarketUser user) throws ExecutionException, InterruptedException {

        long startTime = System.currentTimeMillis();

        // 创建FutureTask对象
        FutureTask<List<MarketAd>> futureTaskBanner = new FutureTask<>(new BannerTask(marketAdMapper));
        FutureTask<List<MarketBrand>> futureTaskBrandList = new FutureTask<>(new BrandListTask(marketBrandMapper, systemConfig));
        FutureTask<List<MarketCategory>> futureTaskChannel = new FutureTask<>(new ChannelTask(marketCategoryMapper));
        FutureTask<List<MarketCoupon>> futureTaskCouponList = new FutureTask<>(new CouponListTask(marketCouponMapper));
        FutureTask<List<WxFloorGoodsVo>> futureTaskFloorGoodsList = new FutureTask<>(new FloorGoodsListTask(marketCategoryMapper, marketGoodsMapper, systemConfig));
        FutureTask<List<MarketGoods>> futureTaskHotGoodsList = new FutureTask<>(new HotGoodsListTask(marketGoodsMapper, systemConfig));
        FutureTask<List<MarketGoods>> futureTaskNewGoodsList = new FutureTask<>(new NewGoodsListTask(marketGoodsMapper, systemConfig));
        FutureTask<List<MarketTopic>> futureTaskTopicList = new FutureTask<>(new TopicListTask(marketTopicMapper, systemConfig));

        // 创建线程对象
        Thread t1 = new Thread(futureTaskBanner);
        Thread t2 = new Thread(futureTaskBrandList);
        Thread t3 = new Thread(futureTaskChannel);
        Thread t4 = new Thread(futureTaskCouponList);
        Thread t5 = new Thread(futureTaskFloorGoodsList);
        Thread t6 = new Thread(futureTaskHotGoodsList);
        Thread t7 = new Thread(futureTaskNewGoodsList);
        Thread t8 = new Thread(futureTaskTopicList);

        // 线程启动
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
        t7.start();
        t8.start();

        // get方法获取返回值
        List<MarketAd> banner = futureTaskBanner.get();
        List<MarketBrand> brandList = futureTaskBrandList.get();
        List<MarketCategory> channel = futureTaskChannel.get();
        List<MarketCoupon> couponList = futureTaskCouponList.get();

        // 用户登录
        if (user != null) {
            Integer userId = user.getId();

            // coupon_user
            MarketCouponUserExample marketCouponUserExample = new MarketCouponUserExample();
            MarketCouponUserExample.Criteria couponUserExampleCriteria = marketCouponUserExample.createCriteria();
            couponUserExampleCriteria.andUserIdEqualTo(userId);
            List<MarketCouponUser> marketCouponUsers = marketCouponUserMapper.selectByExample(marketCouponUserExample);
            List<Integer> couponId = new ArrayList<>();
            for (final MarketCouponUser couponUser : marketCouponUsers) {
                Integer userCouponId = couponUser.getCouponId();
                couponId.add(userCouponId);
            }

            // coupon
            MarketCouponExample marketCouponExample = new MarketCouponExample();
            MarketCouponExample.Criteria couponExampleCriteria = marketCouponExample.createCriteria();
            Short status = 0;
            couponExampleCriteria.andStatusEqualTo(status);
            couponExampleCriteria.andIdNotIn(couponId);
            couponList = marketCouponMapper.selectByExample(marketCouponExample);
            if (couponList != null && couponList.size() > 6) {
                couponList = couponList.subList(0, 6);
            }
        }

        List<WxFloorGoodsVo> floorGoodsList = futureTaskFloorGoodsList.get();
        List<MarketGoods> hotGoodsList = futureTaskHotGoodsList.get();
        List<MarketGoods> newGoodsList = futureTaskNewGoodsList.get();
        List<MarketTopic> topicList = futureTaskTopicList.get();

        // 组装数据并返回
        WxHomeIndexVo wxHomeIndexVo = new WxHomeIndexVo(banner, brandList, channel, couponList, floorGoodsList, hotGoodsList, newGoodsList, topicList);

        long endTime = System.currentTimeMillis();
        System.out.println("Thread Cost time: " + (endTime - startTime) + "ms");

        return wxHomeIndexVo;

    }
}

// banner
@Service
class BannerTask implements Callable<List<MarketAd>> {

    MarketAdMapper marketAdMapper;

    public BannerTask(final MarketAdMapper marketAdMapper) {
        this.marketAdMapper = marketAdMapper;
    }

    @Override
    public List<MarketAd> call() throws Exception {

        MarketAdExample marketAdExample = new MarketAdExample();
        List<MarketAd> banner = marketAdMapper.selectByExample(marketAdExample);
        return banner;
    }
}

// brandList
@Service
class BrandListTask implements Callable<List<MarketBrand>> {

    MarketBrandMapper marketBrandMapper;
    SystemConfig systemConfig;

    public BrandListTask(final MarketBrandMapper marketBrandMapper, final SystemConfig systemConfig) {
        this.marketBrandMapper = marketBrandMapper;
        this.systemConfig = systemConfig;
    }

    @Override
    public List<MarketBrand> call() throws Exception {

        MarketBrandExample marketBrandExample = new MarketBrandExample();
        List<MarketBrand> brandList = marketBrandMapper.selectByExample(marketBrandExample);
        systemConfig.init();
        if (systemConfig.getBrandCount() != null && brandList.size() > systemConfig.getBrandCount()) {
            brandList = brandList.subList(0, systemConfig.getBrandCount());
        }
        return brandList;
    }
}

// channel
@Service
class ChannelTask implements Callable<List<MarketCategory>> {

    MarketCategoryMapper marketCategoryMapper;

    public ChannelTask(final MarketCategoryMapper marketCategoryMapper) {
        this.marketCategoryMapper = marketCategoryMapper;
    }

    @Override
    public List<MarketCategory> call() throws Exception {

        MarketCategoryExample marketCategoryExample = new MarketCategoryExample();
        List<MarketCategory> channel = marketCategoryMapper.selectByExample(marketCategoryExample);
        if (channel != null && channel.size() > 12) {
            channel = channel.subList(0, 12);
        }
        return channel;
    }
}

// couponList
@Service
class CouponListTask implements Callable<List<MarketCoupon>> {

    MarketCouponMapper marketCouponMapper;

    public CouponListTask(final MarketCouponMapper marketCouponMapper) {
        this.marketCouponMapper = marketCouponMapper;
    }

    @Override
    public List<MarketCoupon> call() throws Exception {
        // 用户未登录
        MarketCouponExample marketCouponExample = new MarketCouponExample();
        MarketCouponExample.Criteria criteria = marketCouponExample.createCriteria();
        Short status = 0;
        criteria.andStatusEqualTo(status);
        List<MarketCoupon> couponList = marketCouponMapper.selectByExample(marketCouponExample);
        if (couponList != null && couponList.size() > 6) {
            couponList = couponList.subList(0, 6);
        }
        return couponList;
    }
}

// floorGoodsList
@Service
class FloorGoodsListTask implements Callable<List<WxFloorGoodsVo>> {

    MarketCategoryMapper marketCategoryMapper;
    MarketGoodsMapper marketGoodsMapper;
    SystemConfig systemConfig;

    public FloorGoodsListTask(final MarketCategoryMapper marketCategoryMapper, final MarketGoodsMapper marketGoodsMapper, final SystemConfig systemConfig) {
        this.marketCategoryMapper = marketCategoryMapper;
        this.marketGoodsMapper = marketGoodsMapper;
        this.systemConfig = systemConfig;
    }

    @Override
    public List<WxFloorGoodsVo> call() throws Exception {
        List<MarketCategory> marketCategories = marketCategoryMapper.selectByExample(new MarketCategoryExample());
        Map<Integer, List<MarketCategory>> data = groupByPid(marketCategories);
        List<WxFloorGoodsVo> floorGoodsList = new ArrayList<>();
        List<MarketCategory> categoryListL1 = data.get(0);
        // 设置L1分类展示数量
        systemConfig.init();
        if (systemConfig.getCatalogList() != null && categoryListL1.size() > systemConfig.getCatalogList()) {
            categoryListL1 = categoryListL1.subList(0, systemConfig.getCatalogList());
        }
        for (final MarketCategory categoryL1 : categoryListL1) {
            Integer id = categoryL1.getId();
            String name = categoryL1.getName();
            List<MarketGoods> marketGoodsList = new ArrayList<>();
            List<MarketCategory> categoryListL2 = data.get(categoryL1.getId());
            for (final MarketCategory categoryL2 : categoryListL2) {
                Integer l2Id = categoryL2.getId();
                List<MarketGoods> marketGoods = marketGoodsMapper.selectByCategoryId(l2Id);
                marketGoodsList.addAll(marketGoods);
            }
            // 设置每个L1分类展示商品数量
            if (systemConfig.getCatalogGoods() != null && marketGoodsList.size() > systemConfig.getCatalogGoods()) {
                marketGoodsList = marketGoodsList.subList(0, systemConfig.getCatalogGoods());
            }
            WxFloorGoodsVo wxFloorGoodsVo = new WxFloorGoodsVo(id, name, marketGoodsList);
            floorGoodsList.add(wxFloorGoodsVo);
        }
        return floorGoodsList;
    }

    private Map<Integer, List<MarketCategory>> groupByPid(List<MarketCategory> marketCategories) {

        Map<Integer, List<MarketCategory>> map = new HashMap<>();
        for (MarketCategory category : marketCategories) {
            Integer pid = category.getPid();
            List<MarketCategory> list = map.get(pid);
            if (list == null) {
                list = new ArrayList<>();
            }
            list.add(category);
            map.put(pid, list);
        }
        return map;
    }
}

// hotGoodsList
@Service
class HotGoodsListTask implements Callable<List<MarketGoods>> {

    MarketGoodsMapper marketGoodsMapper;
    SystemConfig systemConfig;

    public HotGoodsListTask(final MarketGoodsMapper marketGoodsMapper, final SystemConfig systemConfig) {
        this.marketGoodsMapper = marketGoodsMapper;
        this.systemConfig = systemConfig;
    }

    @Override
    public List<MarketGoods> call() throws Exception {
        MarketGoodsExample marketGoodsExample = new MarketGoodsExample();
        MarketGoodsExample.Criteria criteria = marketGoodsExample.createCriteria();
        criteria.andIsHotEqualTo(true);
        criteria.andIsOnSaleEqualTo(true);
        // marketGoodsExample.setOrderByClause("update_time" + " " + "desc");
        List<MarketGoods> hotGoodsList = marketGoodsMapper.selectByExample(marketGoodsExample);
        systemConfig.init();
        if (systemConfig.getHotGoodsCount() != null && hotGoodsList.size() > systemConfig.getHotGoodsCount()) {
            hotGoodsList = hotGoodsList.subList(0, systemConfig.getHotGoodsCount());
        }
        return hotGoodsList;
    }
}

// newGoodsList
@Service
class NewGoodsListTask implements Callable<List<MarketGoods>> {

    MarketGoodsMapper marketGoodsMapper;
    SystemConfig systemConfig;

    public NewGoodsListTask(final MarketGoodsMapper marketGoodsMapper, final SystemConfig systemConfig) {
        this.marketGoodsMapper = marketGoodsMapper;
        this.systemConfig = systemConfig;
    }

    @Override
    public List<MarketGoods> call() throws Exception {
        MarketGoodsExample marketGoodsExample2 = new MarketGoodsExample();
        MarketGoodsExample.Criteria criteria2 = marketGoodsExample2.createCriteria();
        criteria2.andIsNewEqualTo(true);
        criteria2.andIsOnSaleEqualTo(true);
        List<MarketGoods> newGoodsList = marketGoodsMapper.selectByExample(marketGoodsExample2);
        systemConfig.init();
        if (systemConfig.getNewGoodsCount() != null && newGoodsList.size() > systemConfig.getNewGoodsCount()) {
            newGoodsList = newGoodsList.subList(0, systemConfig.getNewGoodsCount());
        }
        return newGoodsList;
    }
}

// topicList
@Service
class TopicListTask implements Callable<List<MarketTopic>> {

    MarketTopicMapper marketTopicMapper;
    SystemConfig systemConfig;

    public TopicListTask(final MarketTopicMapper marketTopicMapper, final SystemConfig systemConfig) {
        this.marketTopicMapper = marketTopicMapper;
        this.systemConfig = systemConfig;
    }

    @Override
    public List<MarketTopic> call() throws Exception {
        MarketTopicExample marketTopicExample = new MarketTopicExample();
        List<MarketTopic> topicList = marketTopicMapper.selectByExample(marketTopicExample);
        systemConfig.init();
        if (systemConfig.getTopicCount() != null && topicList.size() > systemConfig.getTopicCount()) {
            topicList = topicList.subList(0, systemConfig.getTopicCount());
        }
        return topicList;
    }
}
